package com.cn.http;

import cn.com.allunion.sms.pojo.Smsbusiness;
import cn.com.allunion.sms.pojo.Smsoperator;
import cn.com.allunion.sms.pojo.Smsrecord;
import cn.com.allunion.sms.service.mybatis.SmsbusinessService;
import cn.com.allunion.sms.service.mybatis.SmsoperatorService;
import cn.com.allunion.sms.service.mybatis.SmsrecordService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.cn.common.implement.CheckTypeImpl;
import com.cn.common.implement.TeleCheckImp;
import com.cn.http.command.SmsCommand;
import com.cn.web.bean.BusinessParam;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class HttpClients {
    private Logger logger = LoggerFactory.getLogger(HttpClients.class);

    SmsbusinessService smsBusinessService;
    SmsrecordService smsRecordService;
    SmsoperatorService smsOperatorService;

    Smsbusiness smsbusiness = null;

    TeleCheckImp teleCheckImp;
    CheckTypeImpl checkTypeImpl;


    int choices = 0;

    /**
     * 电话号码群发分隔符
     */
    private final String phoneNumberGroupSeparator ;
    /**
     * auto 联通默认处理渠道
     */
    private String joinNumAutoUnicom ;
    /**
     * auto 移动默认处理渠道
     */
    private String joinNumAutoMobile ;
    /**
     * auto 电信默认处理渠道
     */
    private String joinNumAutoTelecom ;


    /**
     * 过滤链
     */
    SmsFilterChain smsFilterChain ;

    /**
     * 短信发送执行链，可以拦截指定规则的短信记录
     */
    private HandlerExecutionChain handlerExecutionChain ;

    /**
     * 短信发送命令map
     */
    Map<String, SmsCommand> smsCommandMap ;

    public HttpClients(String phoneNumberGroupSeparator) {
        this.phoneNumberGroupSeparator = phoneNumberGroupSeparator;
    }

    /**
     * 过滤手机号码并发送
     *
     * @param ciphertext JSON字符串
     * @param fromIP     目标地址
     * @return 返回说明
     */
    public String httpClientsChannel(String ciphertext, String fromIP) {
        logger.debug("进入转换方法！");
        String result = "success";

        // 组装request对象
//        SmsRequest request = new DefaultSmsRequest() ;
        // 处理过滤
//        smsFilterChain.doFilter(request);

        // json字符能不能解析（能和不能）
        int states = 2;
        BusinessParam businessParam = null ;
        try {

            logger.debug("接收的数据——————————————" + ciphertext);
            if (ciphertext == null) {
                return "接收的数据为空";
            }
            JSONObject item = JSON.parseObject(ciphertext);
            logger.debug("转换json的数据——————————————" + item.toString());

            businessParam = JSON.parseObject(ciphertext, BusinessParam.class) ;
            businessParam.setIp(fromIP);
        } catch (JSONException e) {
            logger.error(e.getMessage(), e);
            result = "数据格式不正确";
            logger.warn("exception: —————————数据格式不正确———————————");

            return result ; // 数据有问题，那么直接返回
        }

        // 条件1：判断业务（冻结，开启，测试）
        List<Smsbusiness> sList = smsBusinessService.findbyCode(businessParam.getBusinessRecord());

        if (CollectionUtils.isNotEmpty(sList)) {
            smsbusiness = sList.get(0);
            states = Integer.valueOf(smsbusiness.getBusinessState());

            if (logger.isDebugEnabled()) {
                logger.debug("获得的状态######## {}", states);
            }
        }

        if (!businessParam.getSmsOperator().equals("auto")) {
            if (states == 1) {
                Smsoperator smsOperator = smsOperatorService.findOperatorObj(businessParam.getSmsOperator());
                if (smsOperator.getJoinState().equals("0")) {
                    result = "运营商状态关闭";
                    states = 3;
                    if (logger.isDebugEnabled()) {
                        logger.debug("运营商处于关闭状态");
                    }
                }
            }
        }

        // 拆分电话号码为 单个 Smsrecord 对象
        List<Smsrecord> smsRecordList = splitPhoneNumberGroup(businessParam) ;

        switch (states) {
            case -1:
                // 测试：存储
                if (logger.isDebugEnabled()) {
                    logger.debug("switch: -> 进入测试case");
                }
//                  List<SMSRecord> smsRecords = MyNeedObjects(item, fromIP, "");
//                  List<Smsrecord> smsRecords = MyNeedObjects(smsRecordList, "");

                if (smsRecordList.size() != 0) {
                    for (Smsrecord smsRecord : smsRecordList) {
                        String res = smsRecordService.addNewRecord(smsRecord);
                        if (res.equals("failure")) {
                            result = "数据测试存储失败";
                            if (logger.isDebugEnabled()) {
                                logger.debug("数据测试存储失败");
                            }
                        }
                    }
                }
                result = "数据测试存储成功！";
                break;

            case 0:
                if (logger.isDebugEnabled()) {
                    logger.debug("switch: -> 业务已冻结");
                }
                result = "业务已冻结";
                break;

            case 1:
                if (logger.isDebugEnabled()) {
                    logger.debug("switch: -> 进入发送case");
                }
                // 条件1是开启并且条件2是开：存储和MQ
                // 存数据（成功）
                // 给MQ

                // 短信发送前处理
                handlerExecutionChain.applyPreExecute(smsRecordList) ;

                // 获取短信处理渠道
                SmsCommand smsCommand = getSmsCommand(businessParam.getSmsOperator()); // smsCommandMap.get(businessParam.getSmsOperator());

                if (null != smsCommand) {
                    // 处理发送短信记录
                    smsCommand.execute(smsRecordList);
                } else {
                    logger.warn("短信发送渠道代码: {}， 对应的短信发送命令不存在。", businessParam.getSmsOperator());
                    result = "运营商代码无效";
                }
                break;

            case 3:
                logger.warn("switch: -> 运营商状态关闭");
                result = "运营商状态关闭";
                break;
            default:
                logger.warn("switch: -> 业务不存在");
                result = "业务不存在";
                break;
        }


        return result;
    }

    /**
     * 根据短信渠道获取短信发送命令
     * @param smsOperator 运营商渠道
     * @return 短信发送命令
     */
    private SmsCommand getSmsCommand(String smsOperator) {
        if (logger.isInfoEnabled()) {
            logger.info("获取短信发送命令，运营商渠道标识: {}", smsOperator);
        }
        if (StringUtils.isEmpty(smsOperator)) {
            logger.warn("运营商渠道标识为空字符串.");
            return null ;
        }
        SmsCommand smsCommand = smsCommandMap.get(smsOperator);

        if (logger.isInfoEnabled()) {
            logger.info("已获取短信发送命令: {}", smsCommand);
        }
        return smsCommand;
    }

    /**
     * 拆分电话号码
     * @param businessParam 业务调用方提交过来的参数对象
     * @return 拆分后的结果
     */
    private List<Smsrecord> splitPhoneNumberGroup(BusinessParam businessParam) {
        if (logger.isDebugEnabled()) {
            logger.debug("----> 拆分电话号码为: {}", businessParam.getSendNumber());
        }
        List<Smsrecord> smsRecordList = null ;
        if (StringUtils.isNotBlank(businessParam.getSendNumber())) {
            if (-1 != businessParam.getSendNumber().indexOf(phoneNumberGroupSeparator)) { // 多个电话号码
                String[] allnumbers = businessParam.getSendNumber().split(phoneNumberGroupSeparator);
                smsRecordList = new ArrayList<>(allnumbers.length) ;
                Smsrecord smsRecord = null ;

                for (int i = 0; i < allnumbers.length; i++) {
                    smsRecord = getSMSRecord(allnumbers[i], businessParam) ;
                    if (null != smsRecord) {
                        // 加入到集合中
                        smsRecordList.add(smsRecord);
                    }
                }
            } else { // 单个手机号码
                smsRecordList = new ArrayList<>(1) ;
                Smsrecord smsRecord = getSMSRecord(businessParam.getSendNumber(), businessParam) ;
                if (null != smsRecord) {
                    // 加入到集合中
                    smsRecordList.add(smsRecord);
                }
            }
        }

        return smsRecordList;
    }

    /**
     * 根据电话号码和传递的业务参数，获取SMSRecord对象
     * @param phoneNumber 电话号码
     * @param businessParam 传递的业务参数
     * @return
     */
    private Smsrecord getSMSRecord(String phoneNumber, BusinessParam businessParam) {
        if (null == businessParam) {
            return null ;
        }
        Smsrecord smsRecord = null ;
        Smsoperator smsOperator = null;

        if (StringUtils.isNotBlank(phoneNumber)
                && phoneNumber.length() == 11
                && StringUtils.isNumeric(phoneNumber)) { // 电话号码基本有效
            smsRecord = new Smsrecord();
            smsRecord.setSendNumber(phoneNumber);
            smsRecord.setOperatorMessageID("");
            smsRecord.setSendState("3");
            smsRecord.setSmsBusinessRecord(smsbusiness);
            smsRecord.setSendContent(businessParam.getSendContent());
            smsRecord.setFromIP(businessParam.getIp());
            smsRecord.setCreateDate(new Date());
            smsRecord.setUpdateDate(new Date());
            // 自选默认短信发送通道
            if ("auto".equals(businessParam.getSmsOperator())) {
                smsOperator = haveMyOperator(phoneNumber);
                if (null != smsOperator) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("获得的运营商: " + smsOperator.getSmsOperatorName());
                    }

                    smsRecord.setSmsOperator(smsOperator);
                    return smsRecord ;
                } else {
                    logger.warn("电话号码: {}，没有获得到运营商: {}", phoneNumber, businessParam.getSmsOperator());
                }
            } else {
                // 获取指定的 短信通道
                smsOperator = smsOperatorService.findOperatorObj(businessParam.getSmsOperator());
                if (logger.isDebugEnabled()) {
                    logger.debug("获得的运营商: " + smsOperator.getSmsOperatorName());
                }

                smsRecord.setSmsOperator(smsOperator);
                return smsRecord ;
            }
        } else {
            logger.warn("手机号码: {} 格式不正确-----", phoneNumber);
        }

        return null ;
    }

    /**
     * 合并电话号码，电话号码之间使用,间隔，例如：139xxxxx,138xxxxx,182xxxxx
     * @param smsRecords 短信描述对象集合
     * @return 拼接好的电话号码字符串，传入参数为空或者空集合，返回空字符串 ""
     */
//    private String concatPhoneNumber(List<Smsrecord> smsRecords) {
//        if (CollectionUtils.isEmpty(smsRecords)) { // 集合为空
//            return "" ;
//        }
//
//        StringBuilder strBuilder = new StringBuilder() ;
//        if (logger.isDebugEnabled()) {
//            logger.debug("----> 开始拼接电话号码 >");
//        }
//        for (Smsrecord sRecord : smsRecords) {
//            if (logger.isDebugEnabled()) {
//                logger.debug(sRecord.getSendNumber());
//            }
//            strBuilder.append(sRecord.getSendNumber()).append(",") ;
//        }
//        strBuilder.deleteCharAt(strBuilder.length()-1) ;
//        if (logger.isDebugEnabled()) {
//            logger.debug("----> 电话号码拼接结果 =" + strBuilder.toString());
//        }
//        return strBuilder.toString() ;
//    }

    /**
     * 根据给定的 marked 短信通道标识，获取数据该短信通道的短信记录集合
     * @param smsRecords 要发送的短信记录集合
     * @param marked 短信通道标识
     * @return SmsOperator.joinNum 等于给定的短信通道标识marked的所有短信记录集合
     */
//    public List<Smsrecord> MyNeedObjects(List<Smsrecord> smsRecords, String marked) {
//
//        if (StringUtils.isBlank(marked) || CollectionUtils.isEmpty(smsRecords)) {
//            return null ;
//        }
//
//        // 数据 marked 标识短信通道的所有短信记录集合
//        List<Smsrecord> needSmsRecords = new ArrayList<>() ;
//
//        for (Smsrecord sd: smsRecords) {
//            if (marked.equals(sd.getSmsOperator().getJoinNum())) { // 属于这个短信通道的短信
//                needSmsRecords.add(sd);
//            }
//        }
//        // 移除
//        smsRecords.remove(needSmsRecords) ;
//
//        return needSmsRecords ;
//    }

    /**
     * 调用自己写的判定的方法
     *
     * @param numbers
     * @return 运营商
     */
    public Smsoperator haveMyOperator(String numbers) {
        Smsoperator smsOperator = null;

        // 这里是需要将传过来的电话号，判定发给哪个运营商
        // -1:mobile参数为空或者手机号码长度不为11，错误！
        // 10086: 检测是否为移动号段
        // 10010: 检测是否为联通号段
        // 10000: 检测是否为电信号段
        // 11000:检测是否为卫通号段
        // 0:未知运营商
        if (logger.isDebugEnabled()) {
            logger.debug("---> 进入判定的方法");
        }

        int resu = checkTypeImpl.checkthePhone(numbers);
        if (logger.isDebugEnabled()) {
            logger.debug("自己方法判定返回的值: {}", resu);
        }
        if (resu == 10086) {
            smsOperator = smsOperatorService.findOperatorObj(joinNumAutoMobile);

        } else if (resu == 10010) {
            smsOperator = smsOperatorService.findOperatorObj(joinNumAutoUnicom);
        } else if (resu == 10000) {
            smsOperator = smsOperatorService.findOperatorObj(joinNumAutoTelecom);
        } else {
            logger.debug("_________电话号码: {}, 格式不正确_________", numbers);
        }

        if (logger.isDebugEnabled() && null != smsOperator) {
            logger.debug("电话号码: {}, 获取运营商的头: {}", numbers, smsOperator.getJoinNum());
        }

        return smsOperator;
    }

    // public int judgeOperators(String number)
    // {
    //
    // }

    // 根据operating = 1和businessRecord 修改 operatorMessageID
    // 根据operating = 2 和 operatorMessageID 修改 sendState

    /**
     * 根据MQ获得的数据修改运营商标识码
     *
     * @param mqJson JSON字符串
     * @throws JSONException
     */
    public void aboutOperatorMessage(String mqJson) throws JSONException {

        logger.debug("从A端MQ上获取的数据_________" + mqJson);

        JSONObject item = JSONObject.parseObject(mqJson);

        String operating = item.getString("operating");

        logger.debug("获取的操作判断:___________" + operating);

        String operatorMessageID = item.getString("operatorMessageID");
        logger.debug("==2" + operating.equals("2"));
        logger.debug("==1" + operating.equals("1"));
        if (operating.equals("1")) {
            String smsRecordID = item.getString("smsRecordID");

            // 由等待发送状态改为正在发送状态

            if (smsRecordID != null && smsRecordID.contains(phoneNumberGroupSeparator)) {
                // 群发短信
                String[] opermessIDS;
                String[] smsRecordIDS = smsRecordID.split(phoneNumberGroupSeparator);
                if (!operatorMessageID.contains(phoneNumberGroupSeparator)) {
                    opermessIDS = new String[smsRecordIDS.length];
                    for (int i = 0; i < smsRecordIDS.length; i++) {
                        opermessIDS[i] = operatorMessageID;
                    }
                } else {
                    opermessIDS = operatorMessageID.split(phoneNumberGroupSeparator);
                }
                logger.debug("opermessIDS.length" + opermessIDS.length
                        + "smsRecordIDS.length=" + smsRecordIDS.length);
                if (opermessIDS != null && smsRecordIDS != null
                        && opermessIDS.length == smsRecordIDS.length) {
                    for (int i = 0; i < opermessIDS.length; i++) {
                        logger.debug("这是修改operatorMessageID 运营商标识唯一码滴");
                        String result = smsRecordService.updateOperatorMessageID(
                                smsRecordIDS[i].toString(), opermessIDS[i],
                                item.getString("sendState").toString());
                        logger.debug("result:" + result);
                    }
                } else {
                    logger.debug("记录ID集合与运营商唯一标识集合个数不同");
                }

            } else {
                // 单发短信
                logger.debug("这是修改operatorMessageID 运营商标识唯一码滴");
                String i = smsRecordService.updateOperatorMessageID(
                        item.getString("smsRecordID").toString(), item
                                .getString("operatorMessageID").toString(),
                        item.getString("sendState").toString());
                logger.debug("i:" + i);

            }

        } else if (operating.equals("2")) {
            // 由正在发送状态改为相应的状态报告（发送成功或者发送失败）
            logger.debug("这是修改sendstate 发送状态的滴");

            logger.debug("#####################"
                    + item.get("smsOperator").toString());

            Smsoperator operator = smsOperatorService.shenma(item.get("smsOperator").toString());

            logger.debug("获得的运营商的Id" + operator.getSmsOperatorID()
                    + operator.getSmsOperatorName());

            String i = smsRecordService.updateSendState(
                    item.get("operatorMessageID").toString(),
                    item.getString("sendState").toString(),
                    item.getString("sendNumber"));
            // String i =
            // recordAction.updateSendState(item.getString("smsRecordID"),item.getString("sendState").toString());
            logger.debug("这是修改sendstate 的结果" + i);

        } else if (operating.equals("3")) {
            logger.debug("3待定哈！");
        }

    }

    public String getJoinNumAutoUnicom() {
        return joinNumAutoUnicom;
    }

    public void setJoinNumAutoUnicom(String joinNumAutoUnicom) {
        this.joinNumAutoUnicom = joinNumAutoUnicom;
    }

    public String getJoinNumAutoMobile() {
        return joinNumAutoMobile;
    }

    public void setJoinNumAutoMobile(String joinNumAutoMobile) {
        this.joinNumAutoMobile = joinNumAutoMobile;
    }

    public String getJoinNumAutoTelecom() {
        return joinNumAutoTelecom;
    }

    public void setJoinNumAutoTelecom(String joinNumAutoTelecom) {
        this.joinNumAutoTelecom = joinNumAutoTelecom;
    }

    public SmsbusinessService getSmsBusinessService() {
        return smsBusinessService;
    }

    public void setSmsBusinessService(SmsbusinessService smsBusinessService) {
        this.smsBusinessService = smsBusinessService;
    }

    public SmsrecordService getSmsRecordService() {
        return smsRecordService;
    }

    public void setSmsRecordService(SmsrecordService smsRecordService) {
        this.smsRecordService = smsRecordService;
    }

    public SmsoperatorService getSmsOperatorService() {
        return smsOperatorService;
    }

    public void setSmsOperatorService(SmsoperatorService smsOperatorService) {
        this.smsOperatorService = smsOperatorService;
    }

    public CheckTypeImpl getCheckTypeImpl() {
        return checkTypeImpl;
    }

    public void setCheckTypeImpl(CheckTypeImpl checkTypeImpl) {
        this.checkTypeImpl = checkTypeImpl;
    }

    public TeleCheckImp getTeleCheckImp() {
        return teleCheckImp;
    }

    public void setTeleCheckImp(TeleCheckImp teleCheckImp) {
        this.teleCheckImp = teleCheckImp;
    }

    public SmsFilterChain getSmsFilterChain() {
        return smsFilterChain;
    }

    public void setSmsFilterChain(SmsFilterChain smsFilterChain) {
        this.smsFilterChain = smsFilterChain;
    }

    public Map<String, SmsCommand> getSmsCommandMap() {
        return smsCommandMap;
    }

    public void setSmsCommandMap(Map<String, SmsCommand> smsCommandMap) {
        this.smsCommandMap = smsCommandMap;
    }

    public HandlerExecutionChain getHandlerExecutionChain() {
        return handlerExecutionChain;
    }

    public void setHandlerExecutionChain(HandlerExecutionChain handlerExecutionChain) {
        this.handlerExecutionChain = handlerExecutionChain;
    }
}
